#include "Get3DMousePos.h"
#include "ScreenManager.h"
#include "TestState.h"

void Get3DMousePos(const D3DXVECTOR2& mousePos, D3DXVECTOR3* pResult, unsigned char** data)
{	
	ID3D11Texture2D* pSurface;
	HRESULT hr;
	hr = TheScreenManager::Instance()->GetSwapChain()->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pSurface));
	
	ID3D11Texture2D* result = NULL;// = pSurface;
	//mousePos = TheTestState::Instance()->GetMousePos();
	D3D11_BOX box;
	box.top = (UINT)mousePos.y;
	box.left = (UINT)mousePos.x;
	box.bottom = box.top + 1;
	box.right = box.left + 1;
	box.front = 0;
	box.back = 1;

	// create result texture
	D3D11_TEXTURE2D_DESC testTexDesc;
	pSurface->GetDesc(&testTexDesc);
	testTexDesc.Width = 1;
	testTexDesc.Height = 1;
	testTexDesc.MipLevels = 1;
	testTexDesc.ArraySize = 1;
	//testTexDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
	//testTexDesc.SampleDesc.Count = 1;
	//testTexDesc.SampleDesc.Quality = 0;
	testTexDesc.BindFlags = 0;
	testTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
	//testTexDesc.MiscFlags = 0;
	testTexDesc.Usage = D3D11_USAGE_STAGING;
	
	hr = TheScreenManager::Instance()->GetDevice()->CreateTexture2D(&testTexDesc, NULL, &result);

	//ID3D11Resource* inputResource;

	//if (pSurface->swa

	//TheScreenManager::Instance()->GetDeviceContext()->CopyResource(result, pSurface);
	TheScreenManager::Instance()->GetDeviceContext()->CopySubresourceRegion(result, 0, 0, 0, 0, pSurface, 0, &box);

	D3D11_MAPPED_SUBRESOURCE mapDesc;
	hr = TheScreenManager::Instance()->GetDeviceContext()->Map(result, 0, D3D11_MAP_READ_WRITE, 0, &mapDesc);
	//D3DXVECTOR4 pixCol;
	//BYTE pix;
	//const unsigned char* data;
	if (mapDesc.pData != NULL)
	{
		*data = ((unsigned char*)mapDesc.pData);
		//pixCol = *((D3DXVECTOR4*)mapDesc.pData);
	}

	TheScreenManager::Instance()->GetDeviceContext()->Unmap(result, 0);

	// unproject etc: start
	
	D3DXVECTOR3 result1;
	D3D10_VIEWPORT vp;
	vp.MinDepth = 0;
	vp.MaxDepth = 1000;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;
	vp.Height = 600;
	vp.Width = 800;	

	D3DXMATRIX proj = TheScreenManager::Instance()->GetProjectionMatrix();
	D3DXMATRIX view = TheScreenManager::Instance()->GetViewMatrix();
	D3DXMATRIX world;
	D3DXMatrixIdentity(&world);

	float mouseZ = ((int)*data) / 255.0f;
	//mouseZ = (1.0f - mouseZ) * 1.0f;
	D3DXVec3Unproject(&result1, &D3DXVECTOR3(mousePos.x, mousePos.y, 0.0f), &vp, &proj, &view, &world);

	*pResult = result1;
}

float PickColour(const D3DXVECTOR2& mousePos)
{
	int screenW = TheScreenManager::Instance()->GetWindowWidth();
	int screenH = TheScreenManager::Instance()->GetWindowHeight();

	if (mousePos.x > 0.0f && mousePos.x < screenW)
	{
		if (mousePos.y > 0.0f && mousePos.y < screenH)
		{
			float colour = -1.0f;

			ID3D11Texture2D* pSurface;
			HRESULT hr;
			hr = TheScreenManager::Instance()->GetSwapChain()->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pSurface));

			ID3D11Texture2D* result = NULL;
			D3D11_BOX box;
			box.top = (UINT)mousePos.y;
			box.left = (UINT)mousePos.x;
			box.bottom = box.top + 1;
			box.right = box.left + 1;
			box.front = 0;
			box.back = 1;

			// create result texture
			D3D11_TEXTURE2D_DESC testTexDesc;
			pSurface->GetDesc(&testTexDesc);
			testTexDesc.Width = 1;
			testTexDesc.Height = 1;
			testTexDesc.MipLevels = 1;
			testTexDesc.ArraySize = 1;
			testTexDesc.BindFlags = 0;
			testTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
			testTexDesc.Usage = D3D11_USAGE_STAGING;

			hr = TheScreenManager::Instance()->GetDevice()->CreateTexture2D(&testTexDesc, NULL, &result);
			if (hr != S_OK)
			{
				if (pSurface)
				{
					pSurface->Release();
				}
				if (result)
				{
					result->Release();
				}
				return 0;
			}
			TheScreenManager::Instance()->GetDeviceContext()->CopySubresourceRegion(result, 0, 0, 0, 0, pSurface, 0, &box);

			D3D11_MAPPED_SUBRESOURCE mapDesc;
			hr = TheScreenManager::Instance()->GetDeviceContext()->Map(result, 0, D3D11_MAP_READ_WRITE, 0, &mapDesc);
			unsigned char* data;
			if (mapDesc.pData != NULL)
			{
				data = ((unsigned char*)mapDesc.pData);
			}

			TheScreenManager::Instance()->GetDeviceContext()->Unmap(result, 0);

			if (pSurface)
			{
				pSurface->Release();
			}
			if (result)
			{
				result->Release();
			}

			//colour = (float)*data / 255.0f;
			return *data;
		}
	}

	return -1;
}

D3DXVECTOR4 PickColourRGBA(const D3DXVECTOR2& mousePos)
{
	D3DXVECTOR4 finalCol(-1, -1, -1, -1);
	
	int screenW = TheScreenManager::Instance()->GetWindowWidth();
	int screenH = TheScreenManager::Instance()->GetWindowHeight();

	if (mousePos.x > 0.0f && mousePos.x < screenW)
	{
		if (mousePos.y > 0.0f && mousePos.y < screenH)
		{
			float colour = -1.0f;

			ID3D11Texture2D* pSurface;
			HRESULT hr;
			hr = TheScreenManager::Instance()->GetSwapChain()->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pSurface));

			ID3D11Texture2D* result = NULL;
			D3D11_BOX box;
			box.top = (UINT)mousePos.y;
			box.left = (UINT)mousePos.x;
			box.bottom = box.top + 1;
			box.right = box.left + 1;
			box.front = 0;
			box.back = 1;

			// create result texture
			D3D11_TEXTURE2D_DESC testTexDesc;
			pSurface->GetDesc(&testTexDesc);
			testTexDesc.Width = 1;
			testTexDesc.Height = 1;
			testTexDesc.MipLevels = 1;
			testTexDesc.ArraySize = 1;
			testTexDesc.BindFlags = 0;
			testTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
			testTexDesc.Usage = D3D11_USAGE_STAGING;

			hr = TheScreenManager::Instance()->GetDevice()->CreateTexture2D(&testTexDesc, NULL, &result);
			if (hr != S_OK)
			{
				if (pSurface)
				{
					pSurface->Release();
				}
				if (result)
				{
					result->Release();
				}
				return finalCol;
			}
			TheScreenManager::Instance()->GetDeviceContext()->CopySubresourceRegion(result, 0, 0, 0, 0, pSurface, 0, &box);

			D3D11_MAPPED_SUBRESOURCE mapDesc;
			hr = TheScreenManager::Instance()->GetDeviceContext()->Map(result, 0, D3D11_MAP_READ_WRITE, 0, &mapDesc);
			unsigned char* data;
			if (mapDesc.pData != NULL)
			{
				data = ((unsigned char*)mapDesc.pData);
			}

			TheScreenManager::Instance()->GetDeviceContext()->Unmap(result, 0);

			if (pSurface)
			{
				pSurface->Release();
			}
			if (result)
			{
				result->Release();
			}

			//colour = (float)*data / 255.0f;

			finalCol.x = *data;
			finalCol.y = *(data + 1);
			finalCol.z = *(data + 2);
			finalCol.w = *(data + 3);

			return finalCol;
		}
	}
	
	return finalCol;
}